package com.ly.user_system.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ly.user_system.dto.BaseSysLogDTO;
import com.ly.user_system.service.BaseSysLogService;
import com.ly.user_system.utils.UserContextUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.util.ContentCachingRequestWrapper;

import java.util.List;
import java.util.concurrent.CompletableFuture;

@Component
public class LogInterceptor implements HandlerInterceptor {

    @Autowired
    private BaseSysLogService logService;

    @Resource
    private ObjectMapper objectMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 包装请求以支持重复读取body
        ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(request);

        // 构建日志对象
        BaseSysLogDTO dto = new BaseSysLogDTO();
        dto.setIp(getClientIP(request));
        dto.setAction(request.getRequestURI());
        dto.setParams(getRequestParams(wrapper));
        dto.setUserId(UserContextUtil.getUserId());
        // 异步保存日志  todo 线程池管理
        CompletableFuture.runAsync(() -> logService.saveBatch(List.of(dto)));
        return true;
    }

    // 获取客户端IP
    private String getClientIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    // 获取请求参数
    private String getRequestParams(ContentCachingRequestWrapper request) {
        try {
            // GET请求参数
            if ("GET".equalsIgnoreCase(request.getMethod())) {
                return objectMapper.writeValueAsString(request.getParameterMap());
            }
            // POST请求body内容
            byte[] content = request.getContentAsByteArray();
            if (content.length > 0) {
                return new String(content, request.getCharacterEncoding());
            }
        } catch (Exception e) {
            return "参数解析失败";
        }
        return null;
    }
}